import codecs
import json
import os

import jsonlines

import tqdm
import yaml

from .print import *
from .os import *

def load_dict_from_yaml(file_path: str):
    with open(file_path, 'rt', encoding='utf-8') as f:
        dict_1 = yaml.load(f, Loader=yaml.FullLoader)
    return dict_1


def write_dict_to_yaml(dic: dict, file_path: str):
    with open(file_path, 'w', encoding='utf-8') as f:
        yaml.dump(dic, f, default_flow_style=False, allow_unicode=True)

def load_list_from_file_clean(path: str):
    """
    得到不包含换行符的str_list
    :param path:
    :return:
    """
    if not os.path.exists(path):
        print_info(f'load_list_file_clean()_{path}文件不存在')
        return []

    with codecs.open(path, 'r', encoding='utf-8') as f:
        cat_to_name: list = f.read().splitlines()
        # cat_to_name: list = f.readlines() -> 包含换行符
        print_info(f"load_list_file_clean()_数据总条数为:{len(cat_to_name)}path:{path}")
    return cat_to_name
def load_first_row_from_file_clean(path: str):
    """
    得到不包含换行符的第一行,如果文件为空， 则返回“”
    :param path:
    :return:
    """
    if not os.path.exists(path):
        print_info(f'load_first_row_clean()_{path}文件不存在')
        return ""
    with codecs.open(path, 'r', encoding='utf=8') as f:
        cat_to_name: str = f.readline()
    return cat_to_name.strip()


def load_dict_from_json(path) -> dict:
    """"""
    with codecs.open(path, 'r', encoding='utf=8') as f:
        cat_to_name: dict = json.load(f)
        print_info("load_dict_from_json()_数据总条数为:", len(cat_to_name), f"path:{path}")
    return cat_to_name


def load_dict_list_from_jsonl(jsonl_file_path) -> list:
    """"""
    print_info("开始执行: load_dict_list_from_jsonl",  f",path:{jsonl_file_path}")
    with codecs.open(jsonl_file_path, 'r', encoding='utf-8') as f:
        lines = f.readlines()
        lines_res = []
        for line in lines:
            try:
                line = json.loads(line)
                lines_res.append(line)
            except Exception as e:
                print(e)
                continue
    print_info("开始执行: load_dict_list_from_jsonl", f",path:{jsonl_file_path}， 加载完成，数据总条数为:{len(lines_res)}")
    return lines_res


def load_dict_from_scp(label_scp_file: str, silence: bool = False) -> dict:
    """
    得到scp文件的内容,要求key value以空格分割， 第一个为key,剩下的都是value。
    :param silence:
    :param label_scp_file:
    :return:
    """
    res = {}
    with codecs.open(label_scp_file, 'r', encoding='utf-8') as f:
        try:
            lines = f.readlines()
        except Exception as e:
            print(e)
            return {}
        for line in lines:
            line = line.strip()
            items = line.split()
            if len(items) < 2:
                if not silence:
                    print_info(
                        'load_dict_from_scp;warning_gxl:, this row not conform to the regulation of scp(key content) and skip it:',
                        line)
                continue
            elif len(items) == 2:
                res[items[0].strip()] = items[1].strip()
            else:
                # print_info(
                #     'warning_gxl:, this row not conform to the regulation of'
                #     ' scp(key content) and no skip it,第一个为key,剩下的都是value:',
                #     line)
                res[items[0].strip()] = (' '.join(items[1:])).strip()
    total_len = len(res)
    print_info("load_dict_from_scp()_数据总条数为:", total_len, f"path:{label_scp_file}")
    return res


def load_item_list_from_scp(input_scp_path):
    """
    得到scp文件的内容,要求key value以空格分割， 第一个为key,剩下的都是value。
    :param label_scp_file:
    :return:
    """
    item_list = []
    with codecs.open(input_scp_path, 'r', encoding='utf-8') as f:
        try:
            lines = f.readlines()
        except Exception as e:
            print(e)
            return {}
        for line in lines:
            line = line.strip()
            items = line.split()
            if len(items) < 2:
                print_info(
                    'load_dict_from_scp;warning_gxl:, this row not conform to the regulation of scp(key content) and skip it:',
                    )
                continue
            elif len(items) == 2:
                item_list.append((items[0].strip(), items[1].strip()))
            else:
                # print_info(
                #     'warning_gxl:, this row not conform to the regulation of'
                #     ' scp(key content) and no skip it,第一个为key,剩下的都是value:',
                #     line)
                item_list.append((items[0].strip(), ' '.join(items[1:]).strip()))
    total_len = len(item_list)
    print_info("load_dict_from_scp()_数据总条数为:", total_len,  f"path:{input_scp_path}")
    return item_list


def load_tuple_list_from_scp(label_scp_file: str) -> list:
    res = []
    with codecs.open(label_scp_file, 'r', encoding='utf-8') as f:
        lines = f.readlines()
        for line in lines:
            line = line.strip()
            items = line.split()
            if len(items) < 2:
                print_info('warning_gxl:, this row not conform to the regulation of scp(key content) and skip it:',
                              line)
                continue
            elif len(items) == 2:
                res.append((items[0].strip(), items[1].strip()))
            else:
                print_info(
                    'warning_gxl:, this row not conform to the regulation of'
                    ' scp(key content) and no skip it,第一个为key,剩下的都是value:',
                    line)
                res.append((items[0].strip(), ' '.join(items[1:]).strip()))
    total_len = len(res)
    print_info("load_tuple_list_from_scp()_数据总条数为:", total_len,  f"path:{label_scp_file}")
    return res




def write_list_to_file(data_list: list, path: str, is_append: bool = False):
    """
    要求data_list中每个元素(str)末尾没有换行, 该写入程序为每个item生成一个结尾的换行符
    :param data_list:
    :param path:
    :return:
    """
    makedirs_for_file(path)
    print_info("write_list_to_file()_数据总条数为:", len(data_list),  f"path:{path}")
    with codecs.open(path, 'w' if not is_append else 'a', encoding='utf-8') as f:
        for data in data_list:
            f.write(data + '\n')

def write_dict_to_json(dic, json_file_path):
    print_info("write_dict_to_json()_数据总条数为:", len(dic),  f"path:{json_file_path}")
    if "/" not in json_file_path:
        json_file_path = "./" + json_file_path
    makedirs(os.path.dirname(json_file_path),)
    with codecs.open(json_file_path, 'w', encoding='utf-8') as f:
        json.dump(dic, f, ensure_ascii=False, indent=4)


def write_dict_list_to_jsonl(dict_list, jsonl_file_path, is_append: bool = False):
    print_info("write_dict_list_to_jsonl()_数据总条数为:", len(dict_list),  f"path:{jsonl_file_path}")
    makedirs(os.path.dirname(jsonl_file_path))
    # for dic in dict_list:
    #     with jsonlines.open(jsonl_file_path, mode='a') as f:
    #         f.write(dic)
    if is_append:
        mode = 'a'
    else:
        mode = 'w'
    with jsonlines.open(jsonl_file_path, mode=mode) as f:
        f.write_all(dict_list)


def write_single_dict_to_jsonl(dic, jsonl_file_path):
    with jsonlines.open(jsonl_file_path, mode='a') as f:
        f.write(dic)


def write_dict_to_scp(dic: dict, scp_file_path: str, mode = "w"):
    print_info("开始write_dict_to_scp()，数据总条数为:", len(dic),  f"path:{scp_file_path}")
    makedirs(os.path.dirname(scp_file_path))
    with codecs.open(scp_file_path, mode, encoding='utf-8') as f:
        for k, v in dic.items():
            f.write(f"{k} {v}\n")


